from dispatcher.common_utils import constants

from dispatcher.common_utils.beans import BlockBean
from dispatcher.common_utils.clutter_utils import update_task_cache
from dispatcher.common_utils.constants import logger
from dispatcher.routers.dispatch.dispatch_task_model_in import DispatchTaskModel, RetryTimeIntervalModel
from dispatcher.routers.dispatch.dispatch_task_model_out import DispatchTaskResponseModel
from dispatcher.celery_work.handle.handle_tasks import handle_dispatch_task



async def create_dispatch_task(data_block_model: DispatchTaskModel):
    """
    调度任务创建应该有两种状态，创建成功或者失败（参数解析就报错了之类的）
    :param data_block: 字典格式的数据包
    :return:
    """
    # 每一条可以调度的任务都要现在缓存中做记录，并实时的持久化，即使这条任务调度请求失败了，也要记录接收状态
    await update_task_cache(data_block_model.dict())

    bean, flag = BlockBean(data_block_model).init_check_bean()
    if not flag:
        logger.info(f"数据解析错误, msg:{flag.msg}")
        return DispatchTaskResponseModel(code="9999", msg=f"数据解析错误，data_block: {data_block_model.dict()}")

    # 处理即时任务
    if bean.dispatch_type == constants.CURRENT_DISPATCH_TYPE:
        bean.remain_try_times -= 1
        await current_task_handle(bean)
        return DispatchTaskResponseModel(code="0000", msg="即时任务创建成功")

    # 任务可被调度，修改调度状态为RECEIVED
    await update_task_cache(bean.to_dict())


    # 处理延时任务
    if bean.dispatch_type == constants.DELAY_DISPATCH_TYPE:
        await delay_task_handle(bean)
        return DispatchTaskResponseModel(code="0000", msg="延时任务创建成功")

    # 处理定时任务
    if bean.dispatch_type == constants.TIMING_DISPATCH_TYPE:
        await timing_task_handle(bean)
        return DispatchTaskResponseModel(code="0000", msg="定时任务创建成功")


async def current_task_handle(bean: BlockBean):
    """
    即时任务直接开始调度，即时任务没有延时时间
    :param bean: 标准格式的任务块
    :return:
    """
    handle_dispatch_task.async_run(args=(bean.to_dict(),))


async def delay_task_handle(bean: BlockBean):
    """
    延时任务处理，大部分放到celery开始调度，部分放到redis缓存
    :param bean: 标准格式的任务块
    :return:
    """
    # todo 延时任务可能会出现延时过长，或者出现峰值，普通即时任务也能会出现峰值情况
    handle_dispatch_task.async_run(args=(bean.to_dict(),), delay=bean.delay_second)


async def timing_task_handle(bean: BlockBean):
    """
    定时任务
    :param bean: 标准格式的任务块
    :return:
    """
    pass
